/****************************************************************************

 Copyright (C) 2009 Jean Pierre Charalambos. All rights reserved.

 Jean Pierre Charalambos (http://dis.unal.edu.co/profesores/pierre/) is an
 Affiliate Associate Professor of the Faculty of Engineering at National
 University of Colombia (http://www.unal.edu.co/).

 This file is part of maku version 0.1.

 http://code.google.com/p/maku/
 email: jpcharalambosh@unal.edu.co

 This file may be used under the terms of the GNU General Public License 
 versions 2.0 or 3.0 as published by the Free Software Foundation and
 appearing in the COPYING file included in the packaging of this file.

 This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

*****************************************************************************/

#include "viewer.h"
#include "auxviewer.h"

using namespace Qt;
using namespace qglviewer;
using namespace std;

AuxViewer::AuxViewer( Scene * const s, QWidget* parent, const int t, const Viewer *mainV, const QGLWidget* shareWidget)
  : Viewer(s, parent, shareWidget), type(t), viewer(mainV)
{
  visible = false;
  drawMainCamera = false;
  // Forbid rotation
  alignCamera();
  constraint = new WorldConstraint();
  constraint->setRotationConstraintType(AxisPlaneConstraint::FORBIDDEN);
  camera()->frame()->setConstraint(constraint);
}

AuxViewer::AuxViewer( Scene * const s, const QGLFormat & format, QWidget* parent, const int t, const Viewer *mainV, const QGLWidget* shareWidget)
  : Viewer(s, format, parent, shareWidget), type(t), viewer(mainV)
{
  visible = false;
  drawMainCamera = false;
}

void AuxViewer::adjustScene() {
  makeCurrent();
  Vec m(vector_cast<Vec3f>(scene->getBBMin())[0],
        vector_cast<Vec3f>(scene->getBBMin())[1],
	vector_cast<Vec3f>(scene->getBBMin())[2]);
  Vec M(vector_cast<Vec3f>(scene->getBBMax())[0],
        vector_cast<Vec3f>(scene->getBBMax())[1],
	vector_cast<Vec3f>(scene->getBBMax())[2]);
  alignCamera();
  setSceneBoundingBox(m, M);
  //fog
  glFogf( GL_FOG_START,      1.5*sceneRadius() );
  glFogf( GL_FOG_END,        3.0*sceneRadius() );

  setSceneRadius(2.0*(sceneRadius()));
  camera()->setType(Camera::ORTHOGRAPHIC);

  showEntireScene();
}

void AuxViewer::constraintRotation(bool cR) {
  if(cR) {
    alignCamera(camera()->distanceToSceneCenter());
    camera()->frame()->setConstraint(constraint);
    updateGL();
  }
  else
    camera()->frame()->setConstraint(NULL);
}

void AuxViewer::setCameraAsInViewer() {
  camera()->setOrientation( viewer->camera()->orientation() );
  camera()->setPosition( viewer->camera()->position() );
  camera()->setType( viewer->camera()->type() );
  updateGL();
}

void AuxViewer::slotDockVisible(bool v) {
  visible = v;
  if (visible) {
    if (type < 3) {
      // Move camera according to viewer type (on X, Y or Z axis)
      alignCamera();
      camera()->setType(Camera::ORTHOGRAPHIC);
      camera()->showEntireScene();
    }
    updateGL();
    cout << "visible!" << endl;
  }
  else
    cout << "not visible!" << endl;
}

void AuxViewer::draw() {
  makeCurrent();
  if (visible) {
    //attempting to draw camera
    if (viewer!=NULL) {
      if (drawMainCamera) {
        GLfloat curColor[4];
        glGetFloatv(GL_CURRENT_COLOR, curColor);
        glLineWidth(4.0);
        glColor4f(0.0, 1.0, 0.0, 0.5);
        viewer->camera()->draw();
        glLineWidth(1.0);
        glColor4fv(curColor);
      }
    }
    //draw scene
    Viewer::draw();
  }
}
